package com.laituo.juyou.app.api.order;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.laituo.juyou.app.api.order.builder.OrderBuilder;
import com.laituo.juyou.app.api.order.builder.OrderDirector;
import com.laituo.juyou.app.config.alipay.AliProperties;
import com.laituo.juyou.biz.service.freight.FreightBizService;
import com.laituo.juyou.biz.service.order.OrderBizService;
import com.laituo.juyou.biz.service.user.UserBizService;
import com.laituo.juyou.core.Const;
import com.laituo.juyou.core.exception.*;
import com.laituo.juyou.core.ratelimit.annotation.RateLimiter;
import com.laituo.juyou.data.component.CacheComponent;
import com.laituo.juyou.data.component.LockComponent;
import com.laituo.juyou.data.domain.*;
import com.laituo.juyou.data.dto.UserDTO;
import com.laituo.juyou.data.dto.freight.ShipTraceDTO;
import com.laituo.juyou.data.dto.order.OrderDTO;
import com.laituo.juyou.data.dto.order.OrderRequestDTO;
import com.laituo.juyou.data.dto.order.OrderRiderDTO;
import com.laituo.juyou.data.enums.OrderStatusType;
import com.laituo.juyou.data.enums.PayChannelType;
import com.laituo.juyou.data.enums.UserLoginType;
import com.laituo.juyou.data.mapper.*;
import com.laituo.juyou.data.model.Page;
import com.laituo.juyou.data.util.SessionUtil;
import com.laituo.juyou.plugin.core.inter.IPluginPaySuccess;
import com.laituo.juyou.plugin.core.manager.PluginsManager;
import io.goeasy.GoEasy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;

/**
 * Created by rize on 2019/7/4.
 */
@Service
public class OrderServiceImpl implements OrderService {

    private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    private static final String TAKE_ORDER_LOCK = "TAKE_ORDER_";

    @Autowired
    private OrderBuilder orderBuilder;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderSkuMapper orderSkuMapper;

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private LockComponent lockComponent;

    @Autowired
    private OrderBizService orderBizService;

    @Autowired
    private FreightBizService freightBizService;

    @Autowired
    private UserBizService userBizService;

    @Autowired
    private AliProperties aliProperties;

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private GroupShopMapper groupShopMapper;

    @Autowired
    private PluginsManager pluginsManager;

    @Autowired
    private GroupShopUserMapper groupShopUserMapper;

    @Autowired
    private CacheComponent cacheComponent;

    @Autowired
    private UserMapper userMapper;
    /**
     * 微信支付
     */
    @Value("${com.laituo.juyou.wx.mini.app-id}")
    private String wxMiNiAppid;

    @Value("${com.laituo.juyou.wx.app.app-id}")
    private String wxAppAppid;

    @Value("${com.laituo.juyou.wx.h5.app-id}")
    private String wxH5Appid;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @RateLimiter(value = 3)
    public String takeOrder(OrderRequestDTO orderRequest, String channel, Long userId) throws ServiceException {
        if (lockComponent.tryLock(TAKE_ORDER_LOCK + userId, 20)) {
            //加上乐观锁，防止用户重复提交订单
            try {
                OrderDO orderDO = new OrderDO();
                OrderDirector orderDirector = new OrderDirector(orderBuilder);
                orderDirector.constructOrder(orderDO, orderRequest, channel, userId);
                return orderDO.getOrderNo();
            } catch (ServiceException e) {
                throw e;
            } catch (Exception e) {
                logger.error("[提交订单] 异常", e);
                throw new AppServiceException(ExceptionDefinition.ORDER_UNKNOWN_EXCEPTION);
            } finally {
                lockComponent.release(TAKE_ORDER_LOCK + userId);
            }
        }
        throw new AppServiceException(ExceptionDefinition.ORDER_SYSTEM_BUSY);
    }

    @Override
    public Page<OrderDTO> getOrderPage(Integer pageNo, Integer pageSize, String state, Long userId) throws ServiceException {
        List<Integer> status = new ArrayList<>();
        if (state != null) {
            String[] states = state.split(",");
            for (int i = 0; i < states.length; i++) {
                status.add(Integer.parseInt(states[i]));
            }
        }
        List<OrderDTO> orderDTOList = orderMapper.selectOrderPages(status, (pageNo - 1) * pageSize, pageSize, userId);
        Long count = orderMapper.countOrders(status, (pageNo - 1) * pageSize, pageSize, userId);
        //封装SKU
        orderDTOList.forEach(item -> {
            item.setSkuList(orderSkuMapper.selectList(new EntityWrapper<OrderSkuDO>().eq("order_id", item.getId())));
        });
        return new Page<>(orderDTOList, pageNo, pageSize, count);
    }

    @Override
    public OrderDTO getOrderDetail(Long orderId, Long userId) throws ServiceException {
        return orderBizService.getOrderDetail(orderId, userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object wxPrepay(String orderNo, String ip, Long userId) throws ServiceException {
        Date now = new Date();
        OrderDO orderDO = orderBizService.checkOrderExist(orderNo, userId);
        // 检测订单状态
        Integer status = orderDO.getStatus();
        if (status != OrderStatusType.UNPAY.getCode()) {
            throw new AppServiceException(ExceptionDefinition.ORDER_STATUS_NOT_SUPPORT_PAY);
        }
        Integer loginType = SessionUtil.getUser().getLoginType();
        String appId;
        String tradeType;
        if (UserLoginType.MP_WEIXIN.getCode() == loginType) {
            appId = wxMiNiAppid;
            tradeType = WxPayConstants.TradeType.JSAPI;
        } else if (UserLoginType.APP_WEIXIN.getCode() == loginType || UserLoginType.REGISTER.getCode() == loginType) {
            appId = wxAppAppid;
            tradeType = WxPayConstants.TradeType.APP;
        } else if (UserLoginType.H5_WEIXIN.getCode() == loginType) {
            appId = wxH5Appid;
            tradeType = WxPayConstants.TradeType.JSAPI;
        } else {
            throw new AppServiceException(ExceptionDefinition.ORDER_LOGIN_TYPE_NOT_SUPPORT_WXPAY);
        }

        Object result = null;
        try {
            WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
            orderRequest.setOutTradeNo(orderNo);
            orderRequest.setOpenid(SessionUtil.getUser().getOpenId());
            //String nonceStr = String.valueOf(System.currentTimeMillis());
            String nonceStr = "ibuaiVcKdpRxkhJA";
            String body = "订单说明" + orderNo;
            orderRequest.setBody(body);
            orderRequest.setAppid("wxc55b0590c954ef32");
            orderRequest.setTotalFee(orderDO.getActualPrice());
            orderRequest.setSpbillCreateIp(ip);
            orderRequest.setTradeType(tradeType);
            orderRequest.setNonceStr(nonceStr);
            result = wxPayService.createOrder(orderRequest);
            if (result instanceof WxPayMpOrderResult) {
                String prepayId = ((WxPayMpOrderResult) result).getPackageValue();
                prepayId = prepayId.replace("prepay_id=", "");
                UserFormIdDO userFormIdDO = new UserFormIdDO();
                userFormIdDO.setFormId(prepayId);
                userFormIdDO.setUserId(userId);
                userFormIdDO.setOpenid(SessionUtil.getUser().getOpenId());
                userFormIdDO.setGmtUpdate(now);
                userFormIdDO.setGmtCreate(now);
                userBizService.setValidFormId(userFormIdDO);
            }
        } catch (WxPayException e) {
            logger.error("[微信支付] 异常", e);
            throw new ThirdPartServiceException(e.getErrCodeDes(), ExceptionDefinition.THIRD_PART_SERVICE_EXCEPTION.getCode());
        } catch (Exception e) {
            logger.error("[预付款异常]", e);
            throw new AppServiceException(ExceptionDefinition.ORDER_UNKNOWN_EXCEPTION);
        }
        return result;
    }

    /**
     * 支付宝支付
     *
     * @param outTradeNo 订单号
     * @param money      支付钱
     * @return Map
     * @throws ServiceException
     */
    @Override
    public Map aliPay(String outTradeNo, String money) throws ServiceException {
        //判断money是否有小数点
        if (money.indexOf(".") != -1) {
            int index = money.lastIndexOf(".");
            //获取字符串前面的数据
            String subBefore = money.substring(0, index);
            //获取字符串后面数据
            String subBack = money.substring(index + 1, money.length());
            // 判断小数点后数据是否多于两位
            if (subBack.length() > 2) {
                subBack = subBack.substring(0, 2);
                money = subBefore + "." + subBack;
            } else {
                money = subBefore + "." + subBack;
            }
        }
        Map returnMap = new HashMap(16);
        try {
            //构造client
            CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
            //设置网关地址
            certAlipayRequest.setServerUrl(aliProperties.getUrl());
            //设置应用Id
            certAlipayRequest.setAppId(aliProperties.getAppId());
            //设置应用私钥
            certAlipayRequest.setPrivateKey(aliProperties.getPrivateKey());
            //设置请求格式，固定值json
            certAlipayRequest.setFormat(aliProperties.getFormat());
            //设置字符集
            certAlipayRequest.setCharset(aliProperties.getCharset());
            //设置签名类型
            certAlipayRequest.setSignType(aliProperties.getSignType());
            //设置应用公钥证书路径
            certAlipayRequest.setCertPath(aliProperties.getAppCertPath());
            //设置支付宝公钥证书路径
            certAlipayRequest.setAlipayPublicCertPath(aliProperties.getAlipayCertPath());
            //设置支付宝根证书路径
            certAlipayRequest.setRootCertPath(aliProperties.getAlipayRootCertPath());
            //构造client
            AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
            //构造API请求
            AlipayTradeAppPayRequest alipayTradeAppPayRequest = new AlipayTradeAppPayRequest();
            alipayTradeAppPayRequest.setNotifyUrl(aliProperties.getNotifyUrl());
            alipayTradeAppPayRequest.setApiVersion("1.0");
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            model.setBody("订单说明" + outTradeNo);
            model.setSubject(outTradeNo);
            model.setOutTradeNo(outTradeNo);
            model.setTimeoutExpress("90m");
            model.setTotalAmount(money);
            alipayTradeAppPayRequest.setBizModel(model);
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(alipayTradeAppPayRequest);
            String body = response.getBody();
            returnMap.put("body", body);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return returnMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object offlinePrepay(String orderNo, Long userId) throws ServiceException {
        OrderDO orderDO = orderBizService.checkOrderExist(orderNo, userId);
        // 检测订单状态
        Integer status = orderDO.getStatus();
        if (status != OrderStatusType.UNPAY.getCode()) {
            throw new AppServiceException(ExceptionDefinition.ORDER_STATUS_NOT_SUPPORT_PAY);
        }
        OrderDO updateOrderDO = new OrderDO();
        updateOrderDO.setPayChannel(PayChannelType.OFFLINE.getCode());
        updateOrderDO.setStatus(OrderStatusType.WAIT_STOCK.getCode());
        updateOrderDO.setGmtUpdate(new Date());
        boolean succ = orderBizService.changeOrderStatus(orderNo, OrderStatusType.UNPAY.getCode(), updateOrderDO);
        if (succ) {
            return "ok";
        }
        throw new AppServiceException(ExceptionDefinition.ORDER_STATUS_CHANGE_FAILED);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String refund(String orderNo, Long userId) throws ServiceException {
        OrderDO orderDO = orderBizService.checkOrderExist(orderNo, userId);
        if (PayChannelType.OFFLINE.getCode().equals(orderDO.getPayChannel())) {
            throw new AppServiceException(ExceptionDefinition.ORDER_PAY_CHANNEL_NOT_SUPPORT_REFUND);
        }
        if (OrderStatusType.refundable(orderDO.getStatus())) {
            OrderDO updateOrderDO = new OrderDO();
            updateOrderDO.setStatus(OrderStatusType.REFUNDED.getCode());
            orderBizService.changeOrderStatus(orderNo, orderDO.getStatus(), updateOrderDO);
            // GlobalExecutor.execute(() -> {
            OrderDTO orderDTO = new OrderDTO();
            BeanUtils.copyProperties(orderDO, orderDTO);
            List<OrderSkuDO> orderSkuList = orderSkuMapper.selectList(new EntityWrapper<OrderSkuDO>().eq("order_no", orderDO.getOrderNo()));
            orderDTO.setSkuList(orderSkuList);
            // adminNotifyBizService.refundOrder(orderDTO);
            //});
            if (refundDirect(orderDTO)) {
                return "ok";
            }
        }
        throw new AppServiceException(ExceptionDefinition.ORDER_STATUS_NOT_SUPPORT_REFUND);
    }


    private Boolean refundDirect(OrderDTO orderDTO) throws ServiceException {
        String orderNo = orderDTO.getOrderNo();
        if (lockComponent.tryLock(OrderBizService.ORDER_REFUND_LOCK + orderNo, 30)) {
            try {
                //1.校验订单状态是否处于团购状态中
                OrderDO orderDO = orderBizService.checkOrderExist(orderNo, null);
                if (OrderStatusType.refundable(orderDO.getStatus())) {
                    throw new AdminServiceException(ExceptionDefinition.ORDER_STATUS_NOT_SUPPORT_REFUND);
                }
                //2.退款处理
                //2.1.1 先流转状态
                Long userId = orderDO.getUserId();
                UserDTO userDTO = SessionUtil.getUser();
                Integer loginType = userDTO.getLoginType();

                //2.1.2 向微信支付平台发送退款请求
                WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
                wxPayRefundRequest.setAppid(loginType == UserLoginType.MP_WEIXIN.getCode() ? wxMiNiAppid : wxAppAppid);
                wxPayRefundRequest.setOutTradeNo(orderNo);
                wxPayRefundRequest.setOutRefundNo("refund_" + orderNo);
                wxPayRefundRequest.setRefundDesc("用户退款");
                wxPayRefundRequest.setTotalFee(orderDO.getPayPrice() - orderDO.getFreightPrice());
                wxPayRefundRequest.setRefundFee(orderDO.getPayPrice() - orderDO.getFreightPrice());
                WxPayRefundResult wxPayRefundResult = wxPayService.refund(wxPayRefundRequest);
                if (!wxPayRefundResult.getReturnCode().equals("SUCCESS")) {
                    logger.warn("[微信退款] 失败 : " + wxPayRefundResult.getReturnMsg());
                    throw new AdminServiceException(wxPayRefundResult.getReturnMsg(),
                            ExceptionDefinition.THIRD_PART_SERVICE_EXCEPTION.getCode());
                }
                if (!wxPayRefundResult.getResultCode().equals("SUCCESS")) {
                    logger.warn("[微信退款] 失败 : " + wxPayRefundResult.getReturnMsg());
                    throw new AdminServiceException(wxPayRefundResult.getReturnMsg(),
                            ExceptionDefinition.THIRD_PART_SERVICE_EXCEPTION.getCode());
                }
                return true;
            } catch (ServiceException e) {
                throw e;
            } catch (Exception e) {
                logger.error("[微信退款] 异常", e);
                throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
            } finally {
                lockComponent.release(OrderBizService.ORDER_REFUND_LOCK + orderNo);
            }
        } else {
            throw new AdminServiceException(ExceptionDefinition.SYSTEM_BUSY);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String cancel(String orderNo, Long userId) throws ServiceException {
        OrderDO orderDO = orderBizService.checkOrderExist(orderNo, userId);
        if (orderDO.getStatus() != OrderStatusType.UNPAY.getCode()) {
            throw new AppServiceException(ExceptionDefinition.ORDER_STATUS_NOT_SUPPORT_CANCEL);
        }
        OrderDO updateOrderDO = new OrderDO();
        updateOrderDO.setStatus(OrderStatusType.CANCELED.getCode());
        updateOrderDO.setGmtUpdate(new Date());
        orderBizService.changeOrderStatus(orderNo, OrderStatusType.UNPAY.getCode(), updateOrderDO);
        return "ok";
    }

    @Override
    public String confirm(String orderNo, Long userId) throws ServiceException {
        OrderDO orderDO = orderBizService.checkOrderExist(orderNo, userId);
        if (orderDO.getStatus() != OrderStatusType.WAIT_CONFIRM.getCode()) {
            throw new AppServiceException(ExceptionDefinition.ORDER_STATUS_NOT_SUPPORT_CONFIRM);
        }
        OrderDO updateOrderDO = new OrderDO();
        updateOrderDO.setStatus(OrderStatusType.WAIT_APPRAISE.getCode());
        updateOrderDO.setGmtUpdate(new Date());
        orderBizService.changeOrderStatus(orderNo, OrderStatusType.WAIT_CONFIRM.getCode(), updateOrderDO);
        return "ok";
    }

    @Override
    public ShipTraceDTO queryShip(String orderNo, Long userId) throws ServiceException {
        OrderDO orderDO = orderBizService.checkOrderExist(orderNo, userId);
        if (orderDO.getStatus() < OrderStatusType.WAIT_CONFIRM.getCode()) {
            throw new AppServiceException(ExceptionDefinition.ORDER_HAS_NOT_SHIP);
        }
        if (StringUtils.isEmpty(orderDO.getShipCode()) || StringUtils.isEmpty(orderDO.getShipNo())) {
            throw new AppServiceException(ExceptionDefinition.ORDER_DID_NOT_SET_SHIP);
        }
        ShipTraceDTO shipTraceList = freightBizService.getShipTraceList(orderDO.getShipNo(), orderDO.getShipCode());
        if (CollectionUtils.isEmpty(shipTraceList.getTraces())) {
            throw new AppServiceException(ExceptionDefinition.ORDER_DO_NOT_EXIST_SHIP_TRACE);
        }
        return shipTraceList;
    }

    @Override
    public Object notifyTest(String orderNo, String payType, String totalFee, String payId) throws ServiceException {
        List<OrderDO> orderDOList = orderMapper.selectList(
                new EntityWrapper<OrderDO>()
                        .eq("order_no", orderNo));

        if (CollectionUtils.isEmpty(orderDOList)) {
            logger.warn("订单不存在 orderNo=" + orderNo);
            return WxPayNotifyResponse.fail("订单不存在 orderNo=" + orderNo);
        }

        OrderDO order = orderDOList.get(0);

        // 检查这个订单是否已经处理过
        if (order.getStatus() != OrderStatusType.UNPAY.getCode()) {
            logger.warn("订单已经处理成功!" + orderNo);
            return WxPayNotifyResponse.success("订单已经处理成功!");
        }
        // 检查支付订单金额
//        if (!totalFee.equals(order.getActualPrice())) {
//            logger.warn(order.getOrderNo() + " : 支付金额不符合 totalFee=" + totalFee);
//            return WxPayNotifyResponse.fail(order.getOrderNo() + " : 支付金额不符合 totalFee=" + totalFee);
//        }
        //**************** 在此之前都没有 数据库修改 操作 所以前面是直接返回错误的 **********************//

        OrderDO updateOrderDO = new OrderDO();
        updateOrderDO.setPayId(payId);
        updateOrderDO.setPayChannel(payType);
        updateOrderDO.setPayPrice(Integer.parseInt(totalFee));
        updateOrderDO.setGmtPay(new Date());
        updateOrderDO.setGmtUpdate(order.getGmtPay());
        String groupNo = "";
        //团购处理
        if (null != order.getGroupShopId()) {
            Wrapper<GroupShopUserDO> wrapper = new EntityWrapper<GroupShopUserDO>()
                    .eq("order_id", orderNo).eq("status", 0);
            //拼团回调
            List<GroupShopUserDO> groupInfo = groupShopUserMapper.selectList(wrapper);
            //拼团信息
            GroupShopDO groupShopDO = cacheComponent.getHashObj(Const.GROUP_SHOP_INFO, order.getGroupShopId().toString(), GroupShopDO.class);
            if (null == groupShopDO) {
                groupShopDO = groupShopMapper.selectById(order.getGroupShopId());
            }
            if (groupInfo.size() > 0) {
                GroupShopUserDO groupShopUserDO = groupInfo.get(0);
                String raw = cacheComponent.getRaw(Const.GROUP_USER_NUM + groupShopUserDO.getGroupNo());
                int count = Integer.parseInt(StrUtil.isBlank(raw) ? "0" : raw);
                groupNo = groupShopUserDO.getGroupNo();
                if (count == 0) {
                    GroupShopUserDTO groupShopUserDTO = new GroupShopUserDTO();
                    groupShopUserDTO.setCreater(groupShopUserDO.getCreateId());
                    groupShopUserDTO.setGroupShopNo(groupShopUserDO.getGroupNo());
                    groupShopUserDTO.setGmtCreate(groupShopUserDO.getGmtCreate());
                    groupShopUserDTO.setMinNum(groupShopDO.getMinimumNumber());
                    UserDO userDO = userMapper.selectById(groupShopUserDO.getUserId());
                    groupShopUserDTO.setImg(userDO == null ? "-1" : StrUtil.isBlank(userDO.getAvatarUrl()) ? "-1" : userDO.getAvatarUrl());
                    groupShopUserDTO.setUserName(userDO == null ? "-1" : StrUtil.isBlank(userDO.getNickname()) ? "-1" : userDO.getNickname());
                    //半小时失效时间
                    cacheComponent.putObj(Const.GROUP_USER_INFO + groupShopUserDO.getGroupNo(), groupShopUserDTO, Const.CACHE_HALF_HOUR);
                    cacheComponent.putRaw(Const.GROUP_USER_NUM + groupShopUserDO.getGroupNo(), "1", Const.CACHE_HALF_HOUR);
                } else {
                    cacheComponent.incRaw(Const.GROUP_USER_NUM + groupShopUserDO.getGroupNo());
                }
            }
            updateOrderDO.setStatus(OrderStatusType.GROUP_SHOP_WAIT.getCode());
            //修改订单状态 等待拼团
            orderBizService.changeOrderStatus(orderNo, OrderStatusType.UNPAY.getCode(), updateOrderDO);
            //拼单修改状态
            if (order.getGroupShopId() != null && StrUtil.isNotBlank(groupNo)) {

                String raw = cacheComponent.getRaw(Const.GROUP_USER_NUM + groupNo);
                int count = Integer.parseInt(StrUtil.isBlank(raw) ? "0" : raw);
                //拼团成功
                if (count >= groupShopDO.getMinimumNumber()) {
                    Wrapper<GroupShopUserDO> wrapper1 = new EntityWrapper<GroupShopUserDO>().eq("group_no", groupNo).eq("status", 1);
                    List<GroupShopUserDO> info = groupShopUserMapper.selectList(wrapper1);
                    List<String> collect = info.stream().map(item -> {
                        return item.getOrderId();
                    }).collect(Collectors.toList());
                    //订单信息
                    OrderDO updateOrderDO1 = new OrderDO();
                    updateOrderDO1.setStatus(OrderStatusType.WAIT_STOCK.getCode());
                    //拼团人员信息
                    GroupShopUserDO groupShopUserDO = new GroupShopUserDO();
                    //完成拼单
                    groupShopUserDO.setStatus("2");
                    for (String s : collect) {
                        //修改订单状态
                        changeOrderStatus(s, updateOrderDO1, groupShopUserDO);
                    }
                    //修改订单状态
                    changeOrderStatus(orderNo, updateOrderDO1, groupShopUserDO);
                    //删除redis信息
                    cacheComponent.del(Const.GROUP_USER_INFO + groupNo);
                    cacheComponent.del(Const.GROUP_USER_NUM + groupNo);
                    //增加订单信息到redis中
                    collect.add(orderNo);
                    List<OrderDO> orderList = orderMapper.selectList(new EntityWrapper<OrderDO>().in("order_no", collect));
                    for (OrderDO orderDO : orderList) {
                        addRiderOrder(orderDO);
                    }
                } else {
                    GroupShopUserDO groupShopUserDO = new GroupShopUserDO();
                    groupShopUserDO.setStatus("1");
                    groupShopUserMapper.update(groupShopUserDO, wrapper);
                }
            } else {
                logger.warn("支付回调未查询到团购信息!" + orderNo);
            }

        } else {
            updateOrderDO.setStatus(OrderStatusType.WAIT_STOCK.getCode());
            orderBizService.changeOrderStatus(orderNo, OrderStatusType.UNPAY.getCode(), updateOrderDO);
            //提交订单信息到redis,供骑手抢购
            addRiderOrder(order);
            List<OrderSkuDO> orderSkuDOList = orderSkuMapper.selectList(
                    new EntityWrapper<OrderSkuDO>()
                            .eq("order_no", orderNo));
            orderSkuDOList.forEach(item -> {
                //增加销量
                spuMapper.incSales(item.getSpuId(), item.getNum());
                if (order.getGroupShopId() != null) {
                    //增加团购人数, 若想算商品数这里就获取orderSku的数量，若想算人数，这里就写1
                    groupShopMapper.incCurrentNum(order.getGroupShopId(), item.getNum());
                }
            });
            OrderDTO orderDTO = new OrderDTO();
            BeanUtils.copyProperties(order, orderDTO);
            orderDTO.setPayChannel(updateOrderDO.getPayChannel());
            orderDTO.setSkuList(orderSkuDOList);
            List<IPluginPaySuccess> plugins = pluginsManager.getPlugins(IPluginPaySuccess.class);
            if (!CollectionUtils.isEmpty(plugins)) {
                String formId = userBizService.getValidFormIdByUserId(orderDTO.getUserId()).getFormId();
                for (IPluginPaySuccess paySuccess : plugins) {
                    orderDTO = paySuccess.invoke(orderDTO, formId);
                }
            }
        }
        return WxPayNotifyResponse.success("支付成功");
    }

    /**
     * 添加订单数据到redis中
     *
     * @param order
     */
    public void addRiderOrder(OrderDO order) {
        //增加订单信息到redis中
        OrderRiderDTO orderRiderDTO = new OrderRiderDTO();
        StringBuffer toAddress = new StringBuffer(order.getProvince());
        toAddress.append(order.getCity())
                .append(order.getCounty())
                .append(order.getAddress())
                .append(order.getConsignee());
        orderRiderDTO.setGetAddress(order.getStorageName());
        orderRiderDTO.setOrderNo(order.getOrderNo());
        orderRiderDTO.setToAddress(toAddress.toString());
        cacheComponent.putHashRaw(Const.RIDER_ORDER + order.getStoreId(), order.getOrderNo(), JSONUtil.toJsonStr(orderRiderDTO));
        //消息推送
        orderPush();
    }

    /**
     * 消息推送
     */
    public void orderPush() {
        GoEasy goEasy = new GoEasy("http://rest-hangzhou.goeasy.io", "BC-7b7804e8d25e4f3c98115b033e421d2f");
        goEasy.publish("rider_channel", "新订单提醒", "新的订单", "新订单");
    }

    /**
     * 修改订单状态，团组人员状态
     *
     * @param orderNo         订单号
     * @param updateOrderDO1
     * @param groupShopUserDO
     * @throws ServiceException
     */
    public void changeOrderStatus(String orderNo, OrderDO updateOrderDO1, GroupShopUserDO groupShopUserDO) throws ServiceException {
        //修改订单状态
        orderBizService.changeOrderStatus(orderNo, OrderStatusType.GROUP_SHOP_WAIT.getCode(), updateOrderDO1);
        //修改拼单人状态
        Wrapper<GroupShopUserDO> wrapper2 = new EntityWrapper<GroupShopUserDO>().eq("order_id", orderNo);
        groupShopUserMapper.update(groupShopUserDO, wrapper2);
    }

}
